package des.yordan.mihaylov;

/**
 * DES Assignment 2
 * 
 * @author Yordan Mihaylov
 * @version 2011/06/07
 */

public class DES_02 {

	private SimState simState;
	private SimEvent event;

	public DES_02(double arrivalRate, double serviceRate, long max_WQL,
			long simulationDuration) {

		simState = new SimState(arrivalRate, serviceRate, simulationDuration,
				max_WQL);

		SimEvent.setSimState(simState);

		// add init event
		simState.enqueueEvent(new CustomerArrival(0));
		// add simulation termination event
		simState.enqueueEvent(new SimulationTermination(simulationDuration
				* SimState.sec_prescaler));
	}

	public void simulateSingleServer() {

		event = simState.getNextEvent();
		if (null == event) {
			System.out.println("Queue is empty!");
			return;
		}

		while (!simState.isStop() && !(event instanceof SimulationTermination)) {

			long simTm = event.getSimulationTime();
			if (simTm > simState.getNow()) {
				simState.setNow(simTm);
			} else if (simTm < simState.getNow()) {
				System.out
						.println(simState.getNow()
								+ ": ERROR!!! This event should have been processed in the past!");
			}

			event.process();

			event = simState.getNextEvent();
		}
	}

	public static void main(String[] args) {

		long simulationDuration = 10000000; // 10^7s = 10^9 ticks
		double arrivalRate;
		double serviceRate;
		long maxWQL;

		/*
		 * // check arguments if (4 != args.length) { // enter
		 * max_WaitingQueueLength = 0 for infinity System.out .println(
		 * "missing arguments: \"java DES [arrivalRate] [serviceRate] [max_WaitingQueueLength] [simulationDuration]\""
		 * ); return; }
		 * 
		 * long maxWQL = Long.parseLong(args[2]); maxWQL = (maxWQL != 0) ?
		 * maxWQL : Long.MAX_VALUE;
		 * 
		 * DES_02 des1 = new DES_02(Double.parseDouble(args[0]),
		 * Double.parseDouble(args[1]), maxWQL, Long.parseLong(args[3]));
		 */

//		// SYSTEM A
//		System.out
//				.println("------------========== SYSTEM A ==========------------");
//		arrivalRate = 9.5;
//		serviceRate = 10.0;
//		maxWQL = Long.MAX_VALUE;
//
//		DES_02 desA = new DES_02(arrivalRate, serviceRate, maxWQL,
//				simulationDuration);
//
//		desA.simulateSingleServer();
//		desA.simState.printReport();

//		// SYSTEM B
//		System.out
//				.println("\n------------========== SYSTEM B ==========------------");
//		arrivalRate = 9.5;
//		serviceRate = 10.0;
//		maxWQL = 3;
//
//		DES_02 desB = new DES_02(arrivalRate, serviceRate, maxWQL,
//				simulationDuration);
//
//		desB.simulateSingleServer();
//		desB.simState.printReport();

//		// SYSTEM C
//		System.out
//				.println("\n------------========== SYSTEM C ==========------------");
//		arrivalRate = 9.5;
//		serviceRate = 10.0;
//		maxWQL = 10;
//
//		DES_02 desC = new DES_02(arrivalRate, serviceRate, maxWQL,
//				simulationDuration);
//
//		desC.simulateSingleServer();
//		desC.simState.printReport();
//
	//	 SYSTEM D
		System.out
				.println("\n------------========== SYSTEM D ==========------------");
		arrivalRate = 9.;
		serviceRate = 10.0;
		maxWQL = Long.MAX_VALUE;

		DES_02 desD = new DES_02(arrivalRate, serviceRate, maxWQL,
				simulationDuration);
		desD.simState.setDegenerateDistr_arrival_flag(true);
		desD.simState.setDegenerateDistr_service_flag(true);
		desD.simulateSingleServer();
		desD.simState.printReport();
//
		// SYSTEM E
//		System.out
//				.println("\n------------========== SYSTEM E ==========------------");
//		arrivalRate = 9.;
//		serviceRate = 10.0;
//		maxWQL = Long.MAX_VALUE;
//
//		DES_02 desE = new DES_02(arrivalRate, serviceRate, maxWQL,
//				simulationDuration);
//		desE.simState.setDegenerateDistr_service_flag(true);
//		desE.simulateSingleServer();
//		desE.simState.printReport();
//
//		// SYSTEM F
//		System.out
//				.println("\n------------========== SYSTEM F = G ==========------------");
//		arrivalRate = 9.;
//		serviceRate = 10.0;
//		maxWQL = Long.MAX_VALUE;
//
//		DES_02 desF = new DES_02(arrivalRate, serviceRate, maxWQL,
//				simulationDuration);
//		desF.simState.setDegenerateDistr_arrival_flag(true);
//		desF.simulateSingleServer();
//		desF.simState.printReport();
//
//		// SYSTEM G === SYSTEM F

	}
}
